package com.unlcn.ils.wms.backend.service.inspectApp.impl;

import cn.huiyunche.commons.exception.BusinessException;
import com.unlcn.ils.wms.backend.bo.inspectAppBO.TmsInspectExcpConstantBO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.inspectApp.WmsOutboundInspectService;
import com.unlcn.ils.wms.base.dto.WmsInspectForAppDTO;
import com.unlcn.ils.wms.base.dto.WmsOutboundInspectDTO;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundRepairMapper;
import com.unlcn.ils.wms.base.mapper.inspectApp.TmsInspectExcpConstantMapper;
import com.unlcn.ils.wms.base.mapper.inspectApp.WmsOutboundInspectExpandMapper;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundRepair;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundRepairExample;
import com.unlcn.ils.wms.base.model.inspectApp.TmsInspectExcpConstant;
import com.unlcn.ils.wms.base.model.inspectApp.TmsInspectExcpConstantExample;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 出库验车业务
 */
@Service
public class WmsOutboundInspectServiceImpl implements WmsOutboundInspectService {

    private Logger logger = LoggerFactory.getLogger(WmsOutboundInspectServiceImpl.class);

    @Autowired
    private WmsOutboundInspectExpandMapper tmsOutboundInspectExpandMapper;

    @Autowired
    private TmsInspectExcpConstantMapper tmsInspectExcpConstantMapper;

    @Autowired
    private WmsInboundRepairMapper wmsInboundRepairMapper;

    /**
     * 抓取出库单信息
     */
    @Override
    public WmsOutboundInspectDTO selectFetchOutboundBill(String vin, String whCode) {
        logger.info("WmsOutboundInspectServiceImpl.fetchOutboundBill param vin:{}", vin);
        if (StringUtils.isEmpty(vin)) {
            logger.error("WmsOutboundInspectServiceImpl.fetchOutboundBill param vin must not be null");
            throw new IllegalArgumentException("车架号不能为空");
        }
        if (StringUtils.isBlank(whCode)) {
            throw new BusinessException("仓库code不能为空!");
        }
        try {
            //看是否在维修单中
            WmsInboundRepairExample repairExample = new WmsInboundRepairExample();
            repairExample.createCriteria().andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue())
                    .andRpStatusNotEqualTo(String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_COMPLETE.getValue()))
                    .andRpVinEqualTo(vin)
                    .andRpWhCodeEqualTo(whCode);
            List<WmsInboundRepair> wmsInboundRepairs = wmsInboundRepairMapper.selectByExample(repairExample);
            if (CollectionUtils.isNotEmpty(wmsInboundRepairs)) {
                throw new BusinessException("该车架号处于维修状态,需进维修页面进行处理");
            }
            byte del = DeleteFlagEnum.DELETED.getValue();
            byte notQuit = TaskQuitFlagEnum.HAS_QUIT.getValue();//已退库
            String finishedValue = String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue());
            String cancelValue = String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue());
            List<WmsOutboundInspectDTO> wmsOutboundInspectDTOS = null;
            if (vin.trim().length() == 17) {
                //过滤已删除和已退库
                wmsOutboundInspectDTOS = tmsOutboundInspectExpandMapper.selectOutboundByVin(vin, del, notQuit, cancelValue, finishedValue);
            } else {
                wmsOutboundInspectDTOS = tmsOutboundInspectExpandMapper.selectOutboundByWaybillNo(vin, del, notQuit, cancelValue, finishedValue);
            }

            if (CollectionUtils.isEmpty(wmsOutboundInspectDTOS)) {
                throw new BusinessException("未查询到该车架号对应的出库单信息!");
            }

            WmsOutboundInspectDTO inspectDTO = wmsOutboundInspectDTOS.get(0);
            //校验仓库code
            if (!whCode.equals(inspectDTO.getWhcode())) {
                throw new BusinessException("该用户不支持此车架号的仓库操作!");
            }
            //校验是否真实的维修出库释放了库存,已经真实出库的维修单这个车架号就不能再展示
            //判断出库状态(因为涉及重复维修出库的情况,使用其真实释放库存的标识ottype确认该维修单是否出库)
            if (OutBoundTaskTypeEnum.REPAIR_OUT.getCode().equals(inspectDTO.getOtType()))
                throw new BusinessException("该维修单车架号+" + inspectDTO.getVin() + "已经维修出库,不能在此操作");
            if (!Objects.equals(inspectDTO, null)) {
                TmsInspectStatusEnum statusEnum = TmsInspectStatusEnum.getByValue(inspectDTO.getInspectStatusValue());
                if (statusEnum != null) {
                    inspectDTO.setInspectStatusText(statusEnum.getText());
                }
                if (WhCodeEnum.JM_XY.getValue().equals(whCode) || WhCodeEnum.JM_CS.getValue().equals(whCode)) {
                    //君马的带伤发运状态也显示为异常-但是异常不能编辑
                    if (TmsInspectStatusEnum.WAYBILL_DAMAGE.getValue() == inspectDTO.getInspectStatusValue()) {
                        inspectDTO.setInspectStatusText(WmsOutboundInspectStatusEnum.WAYBILL_EXCP.getText());
                    }
                }
                WmsOutboundTaskStatusEnum outboundTaskStatusEnum = WmsOutboundTaskStatusEnum.getByValue(inspectDTO.getOutboundStatus());
                if (outboundTaskStatusEnum != null) {
                    inspectDTO.setOutboundStatusText(outboundTaskStatusEnum.getText());
                }
            }
            return inspectDTO;
        } catch (Exception e) {
            logger.error("WmsOutboundInspectServiceImpl.fetchOutboundBill", e);
            throw new BusinessException("查询出库单异常" + e.getMessage());
        }
    }


    /**
     * 获取九大区域下二级菜单
     */
    @Override
    public List<TmsInspectExcpConstantBO> getInspectExcpList(WmsInspectForAppDTO dto) {
        logger.info("WmsOutboundInspectServiceImpl.getInspectExcpList param  position:{}.", dto);

        if (Objects.equals(dto, null)) {
            throw new BusinessException("参数不能为空!");
        }
        Integer position = dto.getPositionId();
        String whCode = dto.getWhCode();
        if (StringUtils.isBlank(whCode)) {
            throw new BusinessException("仓库code不能为空!");
        }
        if (position == null) {
            throw new BusinessException("positionId不能为空!");
        }
        List<TmsInspectExcpConstantBO> boList = new ArrayList<>();
        TmsInspectExcpConstantExample example = new TmsInspectExcpConstantExample();
        example.createCriteria()
                .andCodeEqualTo(position)
                .andWhCodeEqualTo(whCode);
        List<TmsInspectExcpConstant> list = tmsInspectExcpConstantMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            example = new TmsInspectExcpConstantExample();
            example.createCriteria()
                    .andParentCodeEqualTo(position)
                    .andWhCodeEqualTo(whCode);
            List<TmsInspectExcpConstant> childList = tmsInspectExcpConstantMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(childList)) {
                for (TmsInspectExcpConstant entity : childList) {
                    TmsInspectExcpConstantBO bo = new TmsInspectExcpConstantBO();
                    BeanUtils.copyProperties(entity, bo);
                    example = new TmsInspectExcpConstantExample();
                    example.createCriteria()
                            .andParentCodeEqualTo(entity.getCode())
                            .andWhCodeEqualTo(whCode);
                    List<TmsInspectExcpConstant> childList2 = tmsInspectExcpConstantMapper.selectByExample(example);
                    List<TmsInspectExcpConstantBO> constantExcpList2 = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(childList2)) {
                        for (TmsInspectExcpConstant entity2 : childList2) {
                            TmsInspectExcpConstantBO bo2 = new TmsInspectExcpConstantBO();
                            BeanUtils.copyProperties(entity2, bo2);
                            constantExcpList2.add(bo2);
                        }
                    }
                    bo.setChildExcp(constantExcpList2);
                    boList.add(bo);
                }
            }
        }
        return boList;
    }
}
